package com.sy.simpleegg.platform.whm.util;

import android.util.Base64;
import android.util.Log;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Key;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;

public class DESUtil {
 
    /**
     * 偏移变量，固定占8位字节
     */
    private final static String IV_PARAMETER = "12345678";
    /**
     * 密钥算法
     */
    private static final String ALGORITHM = "DES";
    /**
     * 加密/解密算法-工作模式-填充模式
     */
    private static final String CIPHER_ALGORITHM = "DES/ECB/PKCS7Padding";//"DES/CBC/PKCS5Padding";
    /**
     * 默认编码
     */
    private static final String CHARSET = "utf-8";






    public static void main(String[] args) {
        String s = "你好，HelloWorld！";

        // 加密
//        String s2 = null;
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//            s2 = encrypt("环保NB1233", s);
//        }
//
//        System.out.println("s2===="+s2);
//
//        //解密
//        String s3 = null;
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//            s3 = decrypt("环保NB1233", s2);
//        }
//
//        System.out.println("s3===="+s3);

    }

 
    /**
     * 生成key
     *
     * @param password
     * @return
     * @throws Exception
     */
    private static Key generateKey(String password) throws Exception {
        DESKeySpec dks = new DESKeySpec(password.getBytes(CHARSET));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
        return keyFactory.generateSecret(dks);
    }
 
 
    /**
     * DES加密字符串
     *
     * @param password 加密密码，长度不能够小于8位
     * @param data 待加密字符串
     * @return 加密后内容
     */


//    public static String encrypt(String password, String data) {
//        if (password== null || password.length() < 8) {
//            throw new RuntimeException("加密失败，key不能小于8位");
//        }
//        if (data == null)
//            return null;
//        try {
//            Key secretKey = generateKey(password);
//            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
//            IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET));
//            cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
//            byte[] bytes = cipher.doFinal(data.getBytes(CHARSET));
//
//            //JDK1.8及以上可直接使用Base64，JDK1.7及以下可以使用BASE64Encoder
//            //Android平台可以使用android.util.Base64
//            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//                return new String(Base64.getEncoder().encode(bytes));
//            }else{
//                return  Base64Utils.encode(bytes);
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//            return data;
//        }
//    }
 
    /**
     * DES解密字符串
     *
     * @param password 解密密码，长度不能够小于8位
     * @param data 待解密字符串
     * @return 解密后内容
     */



//    public static String decrypt(String password, String data) {
//        if (password== null || password.length() < 8) {
//            throw new RuntimeException("加密失败，key不能小于8位");
//        }
//        if (data == null)
//            return null;
//        try {
//            Key secretKey = generateKey(password);
//            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
//            IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET));
//            cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
//
//            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//                return new String(cipher.doFinal(Base64.getMimeDecoder().decode(data.getBytes(CHARSET))), CHARSET);
//            }else {
//                return new String(cipher.doFinal(Base64Utils.decode(data)), CHARSET);
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//            return data;
//        }
//    }
 
    /**
     * DES加密文件
     *
     * @param srcFile  待加密的文件
     * @param destFile 加密后存放的文件路径
     * @return 加密后的文件路径
     */
    public static String encryptFile(String password, String srcFile, String destFile) {
 
        if (password== null || password.length() < 8) {
            throw new RuntimeException("加密失败，key不能小于8位");
        }
        try {
            IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET));
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, generateKey(password), iv);
            InputStream is = new FileInputStream(srcFile);
            OutputStream out = new FileOutputStream(destFile);
            CipherInputStream cis = new CipherInputStream(is, cipher);
            byte[] buffer = new byte[1024];
            int r;
            while ((r = cis.read(buffer)) > 0) {
                out.write(buffer, 0, r);
            }
            cis.close();
            is.close();
            out.close();
            return destFile;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }
 
    /**
     * DES解密文件
     *
     * @param srcFile  已加密的文件
     * @param destFile 解密后存放的文件路径
     * @return 解密后的文件路径
     */
    public static String decryptFile(String password, String srcFile, String destFile) {
        if (password== null || password.length() < 8) {
            throw new RuntimeException("加密失败，key不能小于8位");
        }
        try {
            File file = new File(destFile);
            if (!file.exists()) {
                file.getParentFile().mkdirs();
                file.createNewFile();
            }
            IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET));
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, generateKey(password), iv);
            InputStream is = new FileInputStream(srcFile);
            OutputStream out = new FileOutputStream(destFile);
            CipherOutputStream cos = new CipherOutputStream(out, cipher);
            byte[] buffer = new byte[1024];
            int r;
            while ((r = is.read(buffer)) >= 0) {
                cos.write(buffer, 0, r);
            }
            cos.close();
            is.close();
            out.close();
            return destFile;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

//    public static String encryptDES(String encryptData, String encryptKey){
//
//        try {
//            byte[] bytes = encryptKey.getBytes();
//            IvParameterSpec zeroIv = new IvParameterSpec(bytes);
//            SecretKeySpec keySpec = new SecretKeySpec(bytes, "DES");
//            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
////            cipher.init(Cipher.ENCRYPT_MODE, keySpec, zeroIv);
//            cipher.init(Cipher.ENCRYPT_MODE, keySpec);
//            cipher.doFinal(encryptData.getBytes());
//            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//                return new String(Base64.getEncoder().encode(bytes));
//            }else{
//                return  Base64Utils.encode(bytes);
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//            return encryptData;
//        }
//    }
//
//    public static String decryptDES(String decryptData, String decryptKey){
//        try {
//            byte[] bytes = decryptKey.getBytes();
//            SecretKeySpec keySpec = new SecretKeySpec(bytes, "DES");
//            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
//            IvParameterSpec iv = new IvParameterSpec(bytes);
////            cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
//            cipher.init(Cipher.DECRYPT_MODE, keySpec);
//
//            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//                return new String(cipher.doFinal(Base64.getMimeDecoder().decode(decryptData.getBytes(CHARSET))), CHARSET);
//            }else {
////                return new String(cipher.doFinal(Base64Utils.decode(decryptData)), CHARSET);
//                byte[] decodeBytes = Base64Utils.decode(decryptData);
//                byte[] resultBytes = cipher.doFinal(decodeBytes);
//                String result = new String(resultBytes, CHARSET);
//                return result;
//            }
//        }catch (Exception e){
//            e.printStackTrace();
//            return decryptData;
//        }
//    }

    private final static String HEX = "0123456789ABCDEF";
    private final static String TRANSFORMATION = "DES/ECB/PKCS7Padding";//DES是加密方式 CBC是工作模式 PKCS5Padding是填充模式
    private final static String IVPARAMETERSPEC = "01020304";////初始化向量参数，AES 为16bytes. DES 为8bytes.
//    private final static String ALGORITHM = "DES";//DES是加密方式
    private static final String SHA1PRNG = "SHA1PRNG";//// SHA1PRNG 强随机种子算法, 要区别4.2以上版本的调用方法

    /**
     * DES算法，加密
     *
     * @param data 待加密字符串
     * @param key 加密私钥，长度不能够小于8位
     * @return 加密后的字节数组，一般结合Base64编码使用
     */
    public static String encode(String key, String data) {
        return encode(key, data.getBytes());
    }
    /**
     * DES算法，加密
     *
     * @param data 待加密字符串
     * @param key 加密私钥，长度不能够小于8位
     * @return 加密后的字节数组，一般结合Base64编码使用
     */
    public static String encode(String key, byte[] data) {
        try {
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            IvParameterSpec iv = new IvParameterSpec(IVPARAMETERSPEC.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, getRawKey(key));
            byte[] bytes = cipher.doFinal(data);
            return Base64.encodeToString(bytes, Base64.DEFAULT);
        } catch (Exception e) {
            return null;
        }
    }

    public static String encode2(String key, String data) {
        return encode2Bytes(key, data.getBytes());
    }
    public static String encode2Bytes(String key, byte[] data) {
        try {
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            IvParameterSpec iv = new IvParameterSpec(IVPARAMETERSPEC.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, getRawKey(key));
            return byteToHexString(cipher.doFinal(data));
//            return Base64.encodeToString(bytes, Base64.DEFAULT);
        } catch (Exception e) {
            return null;
        }
    }

    public static byte[] encode3(String key, String data) {

        return encode3Bytes(key, hexToByteArray(data));
    }
    public static byte[] encode3Bytes(String key, byte[] data) {
        try {
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            IvParameterSpec iv = new IvParameterSpec(IVPARAMETERSPEC.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, getRawKey(key));
            return cipher.doFinal(data);
//            return Base64.encodeToString(bytes, Base64.DEFAULT);
        } catch (Exception e) {
            return null;
        }
    }

    // 对密钥进行处理
    private static Key getRawKey(String key) throws Exception {
        DESKeySpec dks = new DESKeySpec(key.getBytes());
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
        return keyFactory.generateSecret(dks);
    }

    /**
     * 获取编码后的值
     *
     * @param key
     * @param data
     * @return
     */
    public static String decode(String key, String data) {
        return decode(key, Base64.decode(data, Base64.DEFAULT));
    }

    /**
     * DES算法，解密
     *
     * @param data 待解密字符串
     * @param key 解密私钥，长度不能够小于8位
     * @return 解密后的字节数组
     */
    public static String decode(String key, byte[] data) {
        try {
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            IvParameterSpec iv = new IvParameterSpec(IVPARAMETERSPEC.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, getRawKey(key));
            byte[] original = cipher.doFinal(data);
            String originalString = new String(original);
            return originalString;
        } catch (Exception e) {
            return null;
        }
    }

    public static String decode2(String key, String data) {
//        return decode2(key, Base64.decode(data, Base64.DEFAULT));
        return decode2(key, hexToByteArray(data));
    }
    private static String decode2(String key, byte[] data) {
        try {
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            IvParameterSpec iv = new IvParameterSpec(IVPARAMETERSPEC.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, getRawKey(key));
            byte[] original = cipher.doFinal(data);
            return byteToHexString(original);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     *  byte数组中的每一个byte转为两个字符的十六进制字符
     * */
    public static String byteToHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder(bytes.length);
        String sTemp;
        for (byte aByte : bytes) {
            sTemp = Integer.toHexString(0xFF & aByte);
            if (sTemp.length() < 2) {
                sb.append(0);
            }
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }

    private static byte[] hexToByteArray(String str){
        byte[] result = null;

        try {
            int hexLen = str.length();
            if (hexLen % 2 == 1){
                hexLen ++;
                result = new byte[hexLen / 2];
                str = "0" + str;
            }else{
                result = new byte[hexLen / 2];
            }

            int j = 0;
            for (int i = 0; i < hexLen; i += 2){
                result[j] = hexToByte(str.substring(i, i + 2));
                j ++;
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("DESUtil", "字符串转字节数组异常：" + e.getMessage());
        }

        return result;
    }

    private static byte hexToByte(String hexStr){
        return (byte) Integer.parseInt(hexStr, 16);
    }
}
